package com.hm.PushCaseService.framework.service.session;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.hm.PushCaseService.framework.constant.SecretKey;
import com.hm.PushCaseService.framework.pojo.SessionBean;
import com.hm.PushCaseService.framework.service.crypto.ICryptoService;
import com.hm.PushCaseService.utils.md5.Md5Utils;
import com.hm.PushCaseService.utils.time.TimeDifferenceUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;

import java.util.HashMap;

/**
 * session接口
 */

@Service
public class SessionService implements ISessionService {

    //默认有效期是8小时
    private static final long SURVIVAL_TIME = 1000 * 60 * 60 * 8;

    //sessionID加解密-秘钥
    private static final String SessionSecretKey = "AHTlHk7D3Phq7T9hXDilvL7D3Phm7P70";

    //加密解密服务->用于生成sessionId和校验sessionID
    private final ICryptoService iCryptoService;

    public SessionService(ICryptoService iCryptoService) {
        this.iCryptoService = iCryptoService;
    }

    @Override
    public HashMap<String, String> handleSession(HttpServletRequest request) {
        HashMap<String, String> resMap = new HashMap<>();
        try {
            String body = request.getReader().readLine();
            if (body == null || body.isEmpty()) {
                resMap.put("state", "001");
                resMap.put("msg", "请求体为空");
                return resMap;
            }
            //解析json
            JSONObject jsonObject = (JSONObject) JSON.parse(body);
            String timestamp = jsonObject.getString("timestamp");
            String issue = jsonObject.getString("issue");
            String version = jsonObject.getString("version");
            String channel = jsonObject.getString("channel");
            String author = jsonObject.getString("author");
            String permission = jsonObject.getString("permission");
            String signature = jsonObject.getString("signature");
            //验证时间戳（前后不超过2分钟）
            long timeDifference = TimeDifferenceUtils.calculate(Long.parseLong(timestamp), System.currentTimeMillis());
            long limit = 1000 * 60 * 2;
            if (Math.abs(timeDifference) > limit) {
                //时间戳超时了
                resMap.put("state", "002");
                resMap.put("msg", "timestamp超时");
                return resMap;
            }
            //签名按照顺序channel->version->author->permission->issue全小写再md5
            String s = timestamp.toLowerCase() + channel.toLowerCase() + version.toLowerCase() + author.toLowerCase() + permission.toLowerCase() + issue.toLowerCase();
            String dynamicSignature = Md5Utils.generateMD5(s);
            if (signature == null || !signature.equals(dynamicSignature)) {
                resMap.put("state", "003");
                resMap.put("msg", "无效signature");
                return resMap;
            }
            resMap.put("state", "000");
            resMap.put("secretKey", SecretKey.bodyMap.get(version));
        } catch (Exception e) {
            resMap.put("state", "002");
            resMap.put("secretKey", "处理session失败：" + e.getMessage());
        }
        return resMap;
    }

    @Override
    public HashMap<String, String> verifier(String sessionId) {
        HashMap<String, String> resMap = new HashMap<>();
        try {
            String realSessionId = iCryptoService.decrypt(SessionSecretKey, sessionId);
            SessionBean sessionBean = JSONObject.parseObject(realSessionId, SessionBean.class);
            //判断时间是否超时
            long issueTime = sessionBean.issueTime;
            long timeDifference = TimeDifferenceUtils.calculate(issueTime, System.currentTimeMillis());
            if (Math.abs(timeDifference) > SURVIVAL_TIME) {
                //颁发时间到了
                resMap.put("state", "001");
                resMap.put("msg", "session已过期,请重新登录");
                return resMap;
            }
            resMap.put("state", "000");
            resMap.put("msg", "验证通过");
            //根据版本号获取秘钥
            String secretKeyVersion = sessionBean.secretKeyVersion;
            String secretKey = SecretKey.bodyMap.get(secretKeyVersion);
            resMap.put("secretKey", secretKey);
        } catch (Exception e) {
            resMap.put("state", "002");
            resMap.put("msg", "sessionId验证异常：" + e.getMessage());
        }
        return resMap;
    }

    @Override
    public String generateSessionId() {
        SessionBean sessionBean = new SessionBean();
        sessionBean.issuer = "hm";
        sessionBean.issueTime = System.currentTimeMillis();//发行时间
        sessionBean.secretKeyVersion = SecretKey.SecretKeyVersion_V100;//秘钥版本号
        String jsonString = JSON.toJSONString(sessionBean);
        return iCryptoService.encrypt(SessionSecretKey, jsonString);
    }

}
